// Copyright (c) Appeon. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.

using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace SnapObjects.Data
{
    internal class SqlBuilderComb : ISqlBuilder
    {
        protected ISqlBuilder _builder;
        public SqlBuilderComb(ISqlBuilder builder)
        {
            _builder = builder;
        }

        public string Name => _builder.Name;

        /// <summary>
        ///     Gets the SQL statement type of the current object.
        /// </summary>
        public SqlStatementType SqlType => _builder.SqlType;

        /// <summary>
        ///     Gets an IReadOnlyDictionary<string, ISqlParameter> object that contains all parameters used in the current object.
        /// </summary>
        public IReadOnlyDictionary<string, ISqlParameter> UsedParameters => _builder.UsedParameters;

        /// <summary>
        ///     Adds the parameters which will be used in the SQL statement to the current object.
        /// </summary>
        /// <param name="parameters">
        ///     One or more SQL parameters to be used in the SQL statement. You can use the SqlBuilder.Parameter 
        ///     method to create a SQL parameter.
        /// </param>
        /// <returns>
        ///     Returns false if the parameter name is not specified or the parameter name already exists; otherwise, returns true.
        /// </returns>
        public bool AddParameters(params ISqlParameter[] parameters)
        {
            return _builder.AddParameters(parameters);
        }

        public ISqlBuilder Clone()
        {
            return _builder.Clone();
        }

        /// <summary>
        ///     Gets the placeholder string for a SQL parameter.
        /// </summary>
        /// <param name="name">The name of the SQL parameter to get the placeholder string.</param>
        /// <returns>
        ///     Returns the placeholder string for the SQL parameter if the parameter name exists in the current object.
        /// </returns>
        public string GetParameterPlacehold(string name)
        {
            return _builder.GetParameterPlacehold(name);
        }

        /// <summary>
        ///     Clears the SQL statement and all of the SQL parameters defined in the current object.
        /// </summary>
        /// <returns>Returns the current object.</returns>
        public ISqlBuilder Reset()
        {
            return _builder.Reset();
        }

        /// <summary>
        ///     Gets a read-only ISqlReadOnlyBuilder object generated by the clone of the current object.
        /// </summary>
        /// <returns>
        ///     A read-only ISqlReadOnlyBuilder object which can generate the same SQL statements as the current object.
        /// </returns>
        public ISqlReadOnlyBuilder ToReadOnly()
        {
            return _builder.ToReadOnly();
        }

        /// <summary>
        ///     Returns the raw SQL string for the corresponding database by the current object.
        /// </summary>
        /// <param name="context">
        ///     A DataContext object which contains the database connection information.
        /// </param>
        /// <returns>Returns the raw SQL string.</returns>
        public string ToSqlString(DataContext context)
        {
            return _builder.ToSqlString(context);
        }

        /// <summary>
        ///     Validates the raw SQL string for the specified database generated by the current sqlbuilder.
        /// </summary>
        /// <param name="context">A DataContext object which contains the database connection information.</param>
        /// <param name="throwError">
        ///     True (default ) -- to throw an exception if the raw SQL is not valid in the specified database;
        ///     False -- Not to throw an exception if the raw SQL is not valid in the specified database.
        /// </param>
        /// <returns>
        ///     Returns true if the raw SQL is valid in the specified database; false if the raw SQL is not valid in the specified database.
        /// </returns>
        public bool Validate(DataContext context, bool throwError = true)
        {
            return _builder.Validate(context, throwError);
        }

        public Task<bool> ValidateAsync(DataContext context, bool throwError = true)
        {
            return _builder.ValidateAsync(context, throwError);
        }

        public Task<bool> ValidateAsync(
            DataContext context, bool throwError, CancellationToken cancellationToken = default)
        {
            return _builder.ValidateAsync(context, throwError, cancellationToken);
        }
    }
}
